home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / misc_pto / beav132s / random.c < prev    next >
C/C++ Source or Header  |  1991-11-07  |  30KB  |  1,358 lines

  1. /*
  2. *              Assorted commands.
  3. * The file contains the command
  4. * processors for a large assortment of unrelated
  5. * commands. The only thing they have in common is
  6. * that they are all command processors.
  7. */
  8.  
  9. #include    "def.h"
  10.  
  11. char    backdel ();
  12. bool    fill_out ();
  13. void    bad_key ();
  14.  
  15.  
  16.  
  17. extern    char    MSG_sh_pos[];
  18. extern    char    MSG_sh_pos1[];
  19. extern    char    MSG_f_str[];
  20. extern    char    MSG_3u[];
  21. extern    char    MSG_5u[];
  22. extern    char    MSG_lu[];
  23. extern    char    MSG_03u[];
  24. extern    char    MSG_05u[];
  25. extern    char    MSG_010lu[];
  26. extern    char    MSG_lnk[];
  27. extern    char    MSG_unlink[];
  28. extern    char    MSG_link[];
  29. extern    char    MSG_bad_key[];
  30. extern    char    MSG_esc[];
  31. extern    char    MSG_ctl_x[];
  32. extern    char    MSG_ctl[];
  33. extern    char    MSG_key_code[];
  34. extern    char    char_str[];
  35. extern    char    MSG_w_not_empty[];
  36. extern    char    MSG_procing[];
  37. extern    char    MSG_ok[];
  38. #if RUNCHK
  39. extern    char    ERR_rnd_1[];
  40. extern    char    ERR_rnd_2[];
  41. extern    char    ERR_rnd_3[];
  42. extern    char    ERR_rnd_4[];
  43. extern    char    ERR_rnd_5[];
  44. extern    char    ERR_rnd_6[];
  45. extern    char    ERR_rnd_7[];
  46. #endif
  47.  
  48. extern  ROW_FMT ascii_fmt;
  49. extern  ROW_FMT ebcdic_fmt;
  50. extern  ROW_FMT binary_8_fmt;
  51. extern  ROW_FMT binary_16_fmt;
  52. extern  ROW_FMT binary_32_fmt;
  53. extern  ROW_FMT octal_8_fmt;
  54. extern  ROW_FMT octal_16_fmt;
  55. extern  ROW_FMT octal_32_fmt;
  56. extern  ROW_FMT decimal_8_fmt;
  57. extern  ROW_FMT decimal_16_fmt;
  58. extern  ROW_FMT decimal_32_fmt;
  59. extern  ROW_FMT hex_8_fmt;
  60. extern  ROW_FMT hex_16_fmt;
  61. extern  ROW_FMT hex_32_fmt;
  62.  
  63. extern  bool    read_pat_mode;
  64. extern  bool    dont_repeat;
  65. extern    BUFFER  sav_buf;
  66.  
  67. char    dec_chr_ok ();
  68. ulong   get_long ();
  69. void wind_on_dot_all ();
  70.  
  71. /*
  72. * Display a bunch of useful information about
  73. * the current location of dot and mark.
  74. * The position of the dot and mark and the difference between them.
  75. * The total buffer size is displayed.
  76. * This is normally bound to "C-X =".
  77. */
  78. bool showcpos (f, n, k)
  79. {
  80.  
  81.     A32     dotoff,
  82.         markoff,
  83.         fsize,
  84.         bsize;
  85.     char    buf[NCOL * 2], buf1[NCOL * 2];
  86.  
  87.     dotoff = curwp -> w_dotp -> l_file_offset;
  88.     dotoff += curwp -> w_doto;
  89.  
  90.     if (curwp -> w_markp != NULL)
  91.     {
  92.         markoff = curwp -> w_markp -> l_file_offset;
  93.         markoff += curwp -> w_marko;
  94.     }
  95.  
  96.     bsize = curwp -> w_bufp -> b_linep -> l_bp -> l_file_offset;
  97.     bsize += curwp -> w_bufp -> b_linep -> l_bp -> l_used;
  98.     fsize = curbp -> b_file_size;
  99.  
  100.     if (curwp -> w_markp != NULL)
  101.     {
  102.         /* build format string */
  103.         sprintf (buf1, MSG_sh_pos, R_POS_FMT(curwp), R_POS_FMT(curwp), 
  104.             R_POS_FMT(curwp), R_POS_FMT(curwp));
  105.         sprintf (buf, buf1, dotoff, markoff, bsize, fsize);
  106.     }
  107.     else
  108.     {
  109.         /* build format string */
  110.         sprintf (buf1, MSG_sh_pos1, R_POS_FMT(curwp), R_POS_FMT(curwp), 
  111.             R_POS_FMT(curwp));
  112.         sprintf (buf, buf1, dotoff, bsize, fsize);
  113.     }
  114.  
  115.     sprintf (&buf[strlen(buf)], MSG_f_str, curbp -> b_fname);
  116.     writ_echo (buf);
  117.  
  118.     return (TRUE);
  119. }
  120.  
  121.  
  122. /*
  123. * Twiddle the two characters on either side of
  124. * dot. If dot is at the end of the line twiddle the
  125. * two characters before it. Return with an error if dot
  126. * is at the beginning of line; it seems to be a bit
  127. * pointless to make this work. This fixes up a very
  128. * common typo with a single stroke. Normally bound
  129. * to "C-T". This always works within a line, so
  130. * "WFEDIT" is good enough.
  131. */
  132. bool twiddle ()
  133. {
  134.  
  135.     register    LINE * dotp;
  136.     register short  doto;
  137.     char    b_per_u,
  138.     f_buf[4],
  139.     s_buf[4],
  140.     i;
  141.  
  142.     dotp = curwp -> w_dotp;
  143.     doto = curwp -> w_doto;
  144.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  145.     /* try to move back one unit */
  146.     if (!move_ptr (curwp, (long) - b_per_u, TRUE, TRUE, TRUE))
  147.     {
  148.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  149.         curwp -> w_doto = doto;
  150.         ttbeep ();
  151.         return (FALSE);
  152.     }
  153.     /* pick up first unit byte by byte */
  154.     for (i = 0; i < b_per_u; i++)
  155.     {
  156.         f_buf[i] = DOT_CHAR(curwp);
  157.         move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  158.     }
  159.     /* move to the end of the second unit */
  160.     if (!move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE))
  161.     {
  162.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  163.         curwp -> w_doto = doto;
  164.         ttbeep ();
  165.         return (FALSE);
  166.     }
  167.     /* pick up second unit (reverse order) and deposit second unit */
  168.     for (i = 0; i < b_per_u; i++)
  169.     {
  170.         s_buf[i] = DOT_CHAR(curwp);
  171.         DOT_CHAR(curwp) = f_buf[b_per_u - 1 - i];
  172.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  173.     }
  174.     /* deposit first unit */
  175.     for (i = 0; i < b_per_u; i++)
  176.     {
  177.         DOT_CHAR(curwp) = s_buf[i];
  178.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  179.     }
  180.     curwp -> w_dotp = dotp;
  181.     curwp -> w_doto = doto;
  182.     lchange (WFHARD);
  183.     return (TRUE);
  184. }
  185.  
  186. /*
  187. * Quote the next character, and
  188. * insert it into the buffer. All the characters
  189. * are taken literally.
  190. * The character
  191. * is always read, even if it is inserted 0 times, for
  192. * regularity.
  193. */
  194. bool quote (f, n, k)
  195. {
  196.     register int    c;
  197.  
  198.     if (kbdmop != NULL)
  199.         c = *kbdmop++;
  200.     else
  201.     {
  202.         c = ttgetc ();
  203.         if (kbdmip != NULL)
  204.         {
  205.             if (kbdmip > &kbdm[NKBDM - 4])
  206.             {
  207.                 ctrlg (FALSE, 0, KRANDOM);
  208.                 return (ABORT);
  209.             }
  210.  
  211.             *kbdmip++ = c;
  212.         }
  213.  
  214.     }
  215.  
  216.     if (n < 0)
  217.         return (FALSE);
  218.     if (n == 0)
  219.         return (TRUE);
  220.  
  221.     return (linsert (n, c));
  222. }
  223.  
  224. /*
  225. * Toggle the insert mode.  Insert mode is used only in ASCII or EBCDIC modes.
  226. */
  227. bool insert_toggle ()    /* toggle routine for selfinsert */
  228. {
  229.     register    WINDOW * wp;
  230.  
  231.     if (curbp -> b_flag & BFSLOCK)
  232.         return (TRUE);
  233.  
  234.     if (read_pat_mode)
  235.         dont_repeat = TRUE;
  236.  
  237.     insert_mode = !insert_mode;
  238.     for (wp = wheadp; wp; wp = wp -> w_wndp)
  239.         wp -> w_flag |= WFMODE; /* force mode line update */
  240.     return (TRUE);
  241. }
  242.  
  243. /*
  244. * Ordinary text characters are bound to this function,
  245. * which inserts them into the buffer. Characters marked as control
  246. * characters (using the CTRL flag) may be remapped to their ASCII
  247. * equivalent. This makes TAB (C-I) work right, and also makes the
  248. * world look reasonable if a control character is bound to this
  249. * this routine by hand. Any META or CTLX flags on the character
  250. * are discarded. 
  251. *   Edit the unit under the cursor.
  252. *   Check that the character is valid for the current display mode.
  253. */
  254.  
  255. bool selfinsert (f, n, k)
  256. {
  257.  
  258.     register int    c;
  259.     char    edt_buf[4],
  260.     i_chr,
  261.     b_per_u,
  262.     u_offs,
  263.     u_roffs,
  264.     bit_shf,
  265.     i;
  266.     LINE    * l_ptr;
  267.     short   d_offs;
  268.     int     bytes,
  269.     temp_int;
  270.     long    dot_shf,
  271.     l_mask,
  272.     l_val;
  273.     char    text_buf[12];
  274.     static char max_dec_8[] = "255";
  275.     static char max_dec_16[] = "65535";
  276.     static char max_dec_32[] = "4294967295";
  277.     int        cur_col;
  278.  
  279.     bool intel;
  280.  
  281.     if (n < 0)
  282.     {
  283.         ttbeep ();
  284.         return (FALSE);
  285.     }
  286.     if (n == 0)
  287.     {
  288.         ttbeep ();
  289.         return (TRUE);
  290.     }
  291.     c = k & KCHAR;
  292.     if ((k & KCTRL) != 0 && c >= '@' && c <= '_')/* ASCII-ify.           */
  293.         c -= '@';
  294.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  295.     u_offs = curwp -> w_unit_offset;
  296.     u_roffs = curwp -> w_fmt_ptr -> r_chr_per_u - u_offs - 1;
  297.     intel = curwp -> w_intel_mode;
  298.  
  299.     cur_col = ttcol;
  300.  
  301.     switch (curwp -> w_fmt_ptr -> r_type)
  302.     {
  303.     case EBCDIC:
  304.         c = to_ebcdic (c);  /* convert ASCII to EBCDIC */
  305.     case ASCII:
  306.         if ((insert_mode) || (DOT_POS(curwp) == BUF_SIZE(curwp)))
  307.         {
  308.             linsert (n, c);
  309.             if (read_pat_mode)
  310.                 forwchar (0, 1, KRANDOM);/* advance the cursor */
  311.         }
  312.         else
  313.             lreplace (n, c);
  314.         break;
  315.  
  316.     case HEX:
  317.         if ((c >= '0') && (c <= '9'))
  318.         {
  319.             i_chr = c - '0';/* convert to binary */
  320.         }
  321.         else
  322.             if ((c >= 'A') && (c <= 'F'))
  323.             {
  324.                 i_chr = c - 'A' + 10;/* convert to binary */
  325.             }
  326.             else
  327.                 if ((c >= 'a') && (c <= 'f'))
  328.                 {
  329.                     i_chr = c - 'a' + 10;/* convert to binary */
  330.                 }
  331.                 else
  332.                 {
  333.                     bad_key (k);
  334.                     return (FALSE);
  335.                 }
  336.         fill_out (); /* expand buffer if necessary */
  337.  
  338.         /* position dot to byte to be altered */
  339.         if (intel)
  340.             dot_shf = u_roffs >> 1;
  341.         else
  342.             dot_shf = u_offs >> 1;
  343.  
  344.         /* save dot position for later */
  345.         l_ptr = curwp -> w_dotp;
  346.         d_offs = curwp -> w_doto;
  347.         move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  348.  
  349.         if (u_offs & 1)
  350.         {               /* lower nibble in byte */
  351.             i_chr &= 0x0f;
  352.             DOT_CHAR(curwp) &= 0xf0;
  353.             DOT_CHAR(curwp) |= i_chr;
  354.         }
  355.         else
  356.         {               /* upper nibble in byte */
  357.             i_chr <<= 4;
  358.             i_chr &= 0xf0;
  359.             DOT_CHAR(curwp) &= 0x0f;
  360.             DOT_CHAR(curwp) |= i_chr;
  361.         }
  362.  
  363.         /* restore dot position */
  364.         curwp -> w_dotp = l_ptr;
  365.         curwp -> w_doto = d_offs;
  366.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  367.         break;
  368.  
  369.     case BINARY:
  370.         if ((c != '0') && (c != '1'))
  371.         {
  372.             bad_key (k);
  373.             return (FALSE);
  374.         }
  375.  
  376.         /* position dot to byte to be altered */
  377.         if (intel)
  378.             dot_shf = u_roffs >> 3;
  379.         else
  380.             dot_shf = u_offs >> 3;
  381.  
  382.         fill_out (); /* expand buffer if necessary */
  383.  
  384.         /* save dot position for later */
  385.         l_ptr = curwp -> w_dotp;
  386.         d_offs = curwp -> w_doto;
  387.         move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  388.  
  389.         bit_shf = u_roffs & 0x07;
  390.  
  391.         if (c == '0')
  392.         {
  393.             DOT_CHAR(curwp) &= ~(1 << bit_shf);
  394.         }
  395.         else
  396.         {
  397.             DOT_CHAR(curwp) |= 1 << bit_shf;
  398.         }
  399.  
  400.         /* restore dot position */
  401.         curwp -> w_dotp = l_ptr;
  402.         curwp -> w_doto = d_offs;
  403.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  404.         break;
  405.  
  406.     case OCTAL:
  407.         if (c < '0')
  408.         {
  409.             bad_key (k);
  410.             return (FALSE);
  411.         }
  412.         else
  413.             if ((c > '1') && (u_offs == 0) &&
  414.                 ((curwp -> w_fmt_ptr -> r_size) == WORDS))
  415.             {
  416.                 bad_key (k);
  417.                 return (FALSE);
  418.             }
  419.             else
  420.                 if ((c > '3') && (u_offs == 0))
  421.                 {
  422.                     bad_key (k);
  423.                     return (FALSE);
  424.                 }
  425.                 else
  426.                     if (c > '7')
  427.                     {
  428.                         bad_key (k);
  429.                         return (FALSE);
  430.                     }
  431.  
  432.         dot_shf = (c - '0') & 7;/* get binary value */
  433.         l_mask = 7;         /* create bit mask */
  434.  
  435.         dot_shf <<= (u_roffs * 3);
  436.         l_mask <<= (u_roffs * 3);
  437.  
  438.         fill_out (); /* expand buffer if necessary */
  439.  
  440.         /* save dot position for later */
  441.         l_ptr = curwp -> w_dotp;
  442.         d_offs = curwp -> w_doto;
  443.  
  444.         /* position dot to the byte to be altered */
  445.         if (intel)
  446.         {
  447.             for (i = 0; i < b_per_u; i++)
  448.             {
  449.                 DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  450.                 DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  451.                 l_mask >>= 8;
  452.                 dot_shf >>= 8;
  453.                 move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  454.             }
  455.         }
  456.         else
  457.         {
  458.             move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE);
  459.             /* move to last byte */
  460.             for (i = 0; i < b_per_u; i++)
  461.             {
  462.                 DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  463.                 DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  464.                 l_mask >>= 8;
  465.                 dot_shf >>= 8;
  466.                 move_ptr (curwp, -1L, TRUE, FALSE, TRUE);/* step back one byte */
  467.             }
  468.         }
  469.  
  470.         /* restore dot position */
  471.         curwp -> w_dotp = l_ptr;
  472.         curwp -> w_doto = d_offs;
  473.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  474.         break;
  475.  
  476.     case DECIMAL:
  477.         fill_out (); /* expand buffer if necessary */
  478.  
  479.         /* save dot position for later */
  480.         l_ptr = curwp -> w_dotp;
  481.         d_offs = curwp -> w_doto;
  482.  
  483.         bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u);
  484.         /* if last unit is not full and must be extended */
  485.         for (; bytes < b_per_u; bytes++)
  486.         {
  487.             edt_buf[3] = edt_buf[2];/* shuffle bytes down */
  488.             edt_buf[2] = edt_buf[1];
  489.             edt_buf[1] = edt_buf[0];
  490.             edt_buf[0] = 0;
  491.         }
  492.         switch (curwp -> w_fmt_ptr -> r_size)
  493.         {
  494.         case BYTES:
  495.             sprintf (text_buf, MSG_03u, (int) (edt_buf[0] & 0xff));
  496.             if (!dec_chr_ok (text_buf, max_dec_8, c, u_offs))
  497.             {
  498.                 bad_key (k);
  499.                 return (TRUE);  /* TRUE so that mask will be same len */
  500.             }
  501.             sscanf (text_buf, MSG_3u, &i);/* convert back to binary */
  502.             l_val = (long) i & 0xff;
  503.             break;
  504.  
  505.         case WORDS:
  506.             l_val = get_int (edt_buf);/* do intel swap */
  507.             sprintf (text_buf, MSG_05u, (int) (l_val & 0xFFFF));
  508.             if (!dec_chr_ok (text_buf, max_dec_16, c, u_offs))
  509.             {
  510.                 bad_key (k);
  511.                 return (TRUE);  /* TRUE so that mask will be same len */
  512.             }
  513.             sscanf (text_buf, MSG_5u, &temp_int);
  514.             /* convert back to binary */
  515.             l_val = get_int ((char *) & temp_int);/* do intel swap */
  516.             break;
  517.  
  518.         case DWORDS:
  519.             l_val = get_long (edt_buf);/* do intel swap */
  520.             sprintf (text_buf, MSG_010lu, l_val);
  521.             if (!dec_chr_ok (text_buf, max_dec_32, c, u_offs))
  522.             {
  523.                 bad_key (k);
  524.                 return (TRUE);  /* TRUE so that mask will be same len */
  525.             }
  526.             sscanf (text_buf, MSG_lu, &l_val);
  527.             /* convert back to binary */
  528.             l_val = get_long ((char *) & l_val);/* do intel swap */
  529.             break;
  530. #if RUNCHK
  531.         default:
  532.             writ_echo (ERR_rnd_2);
  533.             break;
  534. #endif
  535.         }
  536.         DOT_CHAR(curwp) = (char) l_val & 0xff;
  537.         for (i = 1; i < b_per_u; i++)
  538.         {
  539.             l_val >>= 8;
  540.             move_ptr (curwp, 1L, TRUE, FALSE, TRUE);/* step forward one byte */
  541.             DOT_CHAR(curwp) = (char) l_val & 0xff;
  542.         }
  543.  
  544.         /* restore dot position */
  545.         curwp -> w_dotp = l_ptr;
  546.         curwp -> w_doto = d_offs;
  547.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  548.         break;
  549.  
  550. #if RUNCHK
  551.     default:
  552.         writ_echo (ERR_rnd_3);
  553.         break;
  554. #endif
  555.     }
  556.     /* if cursor has wrapped to the next line then previous line
  557.         will not be refreshed with WFEDIT so do a WFHARD */
  558.     if (cur_col > get_curcol(curwp))
  559.         lchange (WFHARD);
  560.     else
  561.         lchange (WFEDIT);
  562.  
  563.     return (TRUE);
  564. }
  565.  
  566. /*
  567. *   Insert one unit of zeros at the current dot position.
  568. */
  569. bool    insertunit (f, n, k)
  570. {
  571.     lchange (WFEDIT);
  572.     linsert ((R_B_PER_U(curwp) * n), 0);
  573.     return (TRUE);
  574. }
  575.  
  576. /* 
  577. *   Increase the size of the buffer if necessary.
  578. *   If dot is at the byte after the last full unit
  579. *   then add enough bytes to the buffer to create 
  580. *   a full unit at the end.
  581. */
  582.  
  583. bool    fill_out ()
  584. {
  585.     long    buf_size, dot_pos, last_unit;
  586.     int     b_per_u;
  587.     char    stat, shift;
  588.     int     insert_val;
  589.  
  590.     buf_size = BUF_SIZE(curwp);
  591.     dot_pos = DOT_POS(curwp);
  592.     b_per_u = R_B_PER_U(curwp);
  593.     shift = curwp -> w_disp_shift;
  594.     stat = TRUE;
  595.     insert_val = 0;
  596.     last_unit = buf_size & ~((long)(b_per_u - 1));
  597.     /* there is an even number of units step back one */
  598.     if (last_unit == buf_size)
  599.         last_unit -= b_per_u;
  600.     last_unit += shift;
  601.  
  602.     /* if dot is one byte past the end of the buffer */
  603.     if (dot_pos > last_unit)
  604.     {
  605.         insert_val = b_per_u;
  606.     }
  607.  
  608.     /* if dot is pointed at the end of the buffer */
  609.     else if (dot_pos == last_unit)
  610.     {
  611.         insert_val = b_per_u - (buf_size - last_unit);
  612.     }
  613.  
  614.     /* if insert is necessary then do it */
  615.     if (insert_val != 0)
  616.     {
  617.         lchange (WFHARD);
  618.         move_ptr (curwp, buf_size, TRUE, FALSE, FALSE); /* move dot to end */
  619.         stat = linsert (insert_val, 0);
  620.         move_ptr (curwp, dot_pos, TRUE, TRUE, FALSE); /* put dot back */
  621.     }
  622.     return (stat);
  623. }
  624.  
  625. /*
  626. *   This checks that an entered character is ok
  627. *   for the position given.
  628. */
  629.  
  630. char    dec_chr_ok (char_buf, max_str, chr, pos)
  631.  
  632. char    chr,
  633. pos,
  634. *char_buf,
  635. *max_str;
  636.  
  637. {
  638.     char    i;
  639.  
  640.     if ((chr < '0') || (chr > '9'))
  641.         return (FALSE);
  642.  
  643.     char_buf[pos] = chr;        /* insert typed char */
  644.  
  645.     /* check if number is too big */
  646.     for (i = 0; max_str[i] != 0; i++)
  647.     {
  648.         if (char_buf[i] < max_str[i])
  649.             break;              /* if char is smaller then must be ok */
  650.  
  651.         if (char_buf[i] > max_str[i])
  652.             return (FALSE);     /* val is too large; ERROR */
  653.     }
  654.     return (TRUE);
  655. }
  656.  
  657. /*
  658. * Set the rest of the variables for the mode change.
  659. */
  660. void    set_mode_vars ()
  661. {
  662.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing mode */
  663.     curwp -> w_unit_offset = 0; /* go to end of unit */
  664.     /* if we are in the middle of a search then use the proper format struc */
  665.     if (read_pat_mode)
  666.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  667.  
  668.     wind_on_dot (curwp);
  669.     curwp -> w_flag = WFHARD;
  670.     update ();
  671. }
  672.  
  673. /*
  674. * Change the display mode to ASCII.
  675. * The default binding is META C-A.
  676. */
  677. bool    asciimode ()
  678. {
  679.     curwp -> w_fmt_ptr = &ascii_fmt;
  680.     set_mode_vars ();
  681.     return (TRUE);
  682. }
  683.  
  684. /*
  685. * Change the display mode to EBCDIC.
  686. * The default binding is META C-E.
  687. */
  688. bool    ebcdicmode ()
  689. {
  690.     curwp -> w_fmt_ptr = &ebcdic_fmt;
  691.     set_mode_vars ();
  692.     return (TRUE);
  693. }
  694.  
  695. /*
  696. * Change the display mode to DECIMAL.
  697. * The default binding is META C-D.
  698. */
  699. bool    decimalmode ()
  700. {
  701.     switch (curwp -> w_fmt_ptr -> r_size)
  702.     {
  703.     case BYTES:
  704.         curwp -> w_fmt_ptr = &decimal_8_fmt;
  705.         break;
  706.     case WORDS:
  707.         curwp -> w_fmt_ptr = &decimal_16_fmt;
  708.         break;
  709.  
  710.     case DWORDS:
  711.         curwp -> w_fmt_ptr = &decimal_32_fmt;
  712.         break;
  713. #if RUNCHK
  714.     default:
  715.         writ_echo (ERR_rnd_4);
  716.         break;
  717. #endif
  718.     }
  719.     set_mode_vars ();
  720.     return (TRUE);
  721. }
  722.  
  723. /*
  724. * Change the display mode to HEXADECIMAL.
  725. * The default binding is META C-H.
  726. */
  727. bool    hexmode ()
  728. {
  729.     switch (curwp -> w_fmt_ptr -> r_size)
  730.     {
  731.     case BYTES:
  732.         curwp -> w_fmt_ptr = &hex_8_fmt;
  733.         break;
  734.     case WORDS:
  735.         curwp -> w_fmt_ptr = &hex_16_fmt;
  736.         break;
  737.     case DWORDS:
  738.         curwp -> w_fmt_ptr = &hex_32_fmt;
  739.         break;
  740. #if RUNCHK
  741.     default:
  742.         writ_echo (ERR_rnd_5);
  743.         break;
  744. #endif
  745.     }
  746.     set_mode_vars ();
  747.     return (TRUE);
  748. }
  749.  
  750. /*
  751. * Change the display mode to OCTAL.
  752. * The default binding is META C-O.
  753. */
  754. bool    octalmode ()
  755. {
  756.     switch (curwp -> w_fmt_ptr -> r_size)
  757.     {
  758.     case BYTES:
  759.         curwp -> w_fmt_ptr = &octal_8_fmt;
  760.         break;
  761.  
  762.     case WORDS:
  763.         curwp -> w_fmt_ptr = &octal_16_fmt;
  764.         break;
  765.  
  766.     case DWORDS:
  767.         curwp -> w_fmt_ptr = &octal_32_fmt;
  768.         break;
  769. #if RUNCHK
  770.     default:
  771.         writ_echo (ERR_rnd_6);
  772.         break;
  773. #endif
  774.     }
  775.     set_mode_vars ();
  776.     return (TRUE);
  777. }
  778.  
  779. /*
  780. * Change the display mode to BINARY.
  781. * The default binding is META C-B.
  782. */
  783. bool    binarymode ()
  784. {
  785.     switch (curwp -> w_fmt_ptr -> r_size)
  786.     {
  787.     case BYTES:
  788.         curwp -> w_fmt_ptr = &binary_8_fmt;
  789.         break;
  790.     case WORDS:
  791.         curwp -> w_fmt_ptr = &binary_16_fmt;
  792.         break;
  793.     case DWORDS:
  794.         curwp -> w_fmt_ptr = &binary_32_fmt;
  795.         break;
  796. #if RUNCHK
  797.     default:
  798.         writ_echo (ERR_rnd_7);
  799.         break;
  800. #endif
  801.     }
  802.     set_mode_vars ();
  803.     return (TRUE);
  804. }
  805.  
  806. /*
  807. * Change the display shift.
  808. * Circularly rotate through display shift of 0 through 3.
  809. * This value is used to shift the display by the designated number of bytes.
  810. * This is used to cause WORD and DWORD values to be calculated
  811. * from the correct offset.
  812. */
  813. bool dispshift (f, n, k)
  814. {
  815.     char    mode,
  816.     size;
  817.  
  818.     if (read_pat_mode)
  819.         return (TRUE);  /* no shift is allowed in search mode */
  820.  
  821.  
  822.     mode = curwp -> w_fmt_ptr -> r_type;
  823.     size = curwp -> w_fmt_ptr -> r_size;
  824.  
  825.     if (((mode == HEX) ||
  826.         (mode == DECIMAL) ||
  827.         (mode == BINARY) ||
  828.         (mode == OCTAL)) &&
  829.         (size != BYTES))
  830.     {
  831.         if ((size == WORDS) &&
  832.             (curwp -> w_disp_shift >= 1))
  833.         {                   /* roll over on words */
  834.             curwp -> w_disp_shift = 0;
  835.         }
  836.         else
  837.             if ((size == DWORDS) &&
  838.                 (curwp -> w_disp_shift >= 3))
  839.             {               /* roll over on double words */
  840.                 curwp -> w_disp_shift = 0;
  841.             }
  842.             else
  843.             {
  844.                 curwp -> w_disp_shift++;/* increment shift */
  845.             }
  846.     }
  847.     else
  848.     {
  849.         curwp -> w_disp_shift = 0;/* set to no shift */
  850.     }
  851.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  852.     wind_on_dot (curwp);
  853.     curwp -> w_flag = WFHARD;   /* force full window refresh */
  854.     return (TRUE);
  855. }
  856.  
  857. /*
  858. * Delete forward. This is real
  859. * easy, because the basic delete routine does
  860. * all of the work. Watches for negative arguments,
  861. * and does the right thing. If any argument is
  862. * present, it kills rather than deletes, to prevent
  863. * loss of text if typed with a big argument.
  864. * Normally bound to "C-D".
  865. */
  866. char    forwdel (f, n, k)
  867. {
  868.     char    s;
  869.  
  870.     if (n < 0)
  871.         return (backdel (f, -n, KRANDOM));
  872.  
  873.     s = FALSE;
  874.     if (R_SIZE(curwp) == BYTES)
  875.     {
  876.         if (f != FALSE)
  877.         {
  878.             /* Really a kill.       */
  879.             if ((lastflag & CFKILL) == 0)
  880.                 bclear (&sav_buf);
  881.             thisflag |= CFKILL;
  882.         }
  883.         s = ldelete ((A32)n, f);
  884.         curwp -> w_unit_offset = 0;
  885.     }
  886.     return (s);
  887. }
  888.  
  889.  
  890. /*
  891. * Delete backwards. This is quite easy too,
  892. * because it's all done with other functions. Just
  893. * move the cursor back, and delete forwards.
  894. * Like delete forward, this actually does a kill
  895. * if presented with an argument.
  896. */
  897. char    backdel (f, n, k)
  898. {
  899.  
  900.     int     u_off;
  901.     char    s;
  902.  
  903.     if (n < 0)
  904.         return (forwdel (f, -n, KRANDOM));
  905.  
  906.     s = FALSE;
  907.     if (R_SIZE(curwp) == BYTES)
  908.     {
  909.         u_off = curwp -> w_unit_offset;
  910.         curwp -> w_unit_offset = 0;
  911.         if ((s = backchar (f, n * R_CHR_PER_U(curwp), KRANDOM)) == TRUE)
  912.         {
  913.             s = ldelete ((A32)n, f);
  914.             if (f != FALSE)
  915.             {
  916.                 /* Really a kill.       */
  917.                 if ((lastflag & CFKILL) == 0)
  918.                     bclear (&sav_buf);
  919.                 thisflag |= CFKILL;
  920.             }
  921.         }
  922.         curwp -> w_unit_offset = u_off;
  923.     }
  924.     return (s);
  925. }
  926.  
  927.  
  928. /*
  929. * Change the size of the display unit to BYTE.
  930. * Adjust byte shift to the allowable range.
  931. * Normally bound to "META-1".
  932. */
  933. bool dispsize1 ()
  934. {
  935.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  936.     curwp -> w_unit_offset = 0; /* go to end of unit */
  937.  
  938.     switch (R_TYPE(curwp))
  939.     {
  940.     case OCTAL:
  941.         curwp -> w_fmt_ptr = &octal_8_fmt;
  942.         break;
  943.  
  944.     case DECIMAL:
  945.         curwp -> w_fmt_ptr = &decimal_8_fmt;
  946.         break;
  947.  
  948.     case HEX:
  949.         curwp -> w_fmt_ptr = &hex_8_fmt;
  950.         break;
  951.  
  952.     case BINARY:
  953.         curwp -> w_fmt_ptr = &binary_8_fmt;
  954.         break;
  955.  
  956.     default:
  957.         return (TRUE);
  958.         break;
  959.     }
  960.  
  961.     /* if we are in the middle of a search then use the proper format struc */
  962.     if (read_pat_mode)
  963.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  964.  
  965.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  966.     wind_on_dot (curwp);
  967.     curwp -> w_flag = WFHARD;
  968.     update ();
  969.     return (TRUE);
  970. }
  971.  
  972. /*
  973. * Change the size of the display unit to WORD.
  974. * Adjust byte shift to the allowable range.
  975. * Normally bound to "META-2".
  976. */
  977. bool dispsize2 ()
  978. {
  979.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  980.     curwp -> w_unit_offset = 0; /* go to end of unit */
  981.  
  982.     switch (R_TYPE(curwp))
  983.     {
  984.     case OCTAL:
  985.         curwp -> w_fmt_ptr = &octal_16_fmt;
  986.         break;
  987.  
  988.     case DECIMAL:
  989.         curwp -> w_fmt_ptr = &decimal_16_fmt;
  990.         break;
  991.  
  992.     case HEX:
  993.         curwp -> w_fmt_ptr = &hex_16_fmt;
  994.         break;
  995.  
  996.     case BINARY:
  997.         curwp -> w_fmt_ptr = &binary_16_fmt;
  998.         break;
  999.  
  1000.     default:
  1001.         return (TRUE);
  1002.         break;
  1003.     }
  1004.  
  1005.     /* if we are in the middle of a search then use the proper format struc */
  1006.     if (read_pat_mode)
  1007.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1008.  
  1009.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1010.     wind_on_dot (curwp);
  1011.     curwp -> w_flag = WFHARD;
  1012.     update ();
  1013.     return (TRUE);
  1014. }
  1015.  
  1016. /*
  1017. * Change the size of the display unit to DOUBLE WORD.
  1018. * Adjust byte shift to the allowable range.
  1019. * Normally bound to "META-4".
  1020. */
  1021. bool dispsize4 ()
  1022. {
  1023.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  1024.     curwp -> w_unit_offset = 0; /* go to end of unit */
  1025.  
  1026.     switch (R_TYPE(curwp))
  1027.     {
  1028.     case OCTAL:
  1029.         curwp -> w_fmt_ptr = &octal_32_fmt;
  1030.         break;
  1031.  
  1032.     case DECIMAL:
  1033.         curwp -> w_fmt_ptr = &decimal_32_fmt;
  1034.         break;
  1035.  
  1036.     case HEX:
  1037.         curwp -> w_fmt_ptr = &hex_32_fmt;
  1038.         break;
  1039.  
  1040.     case BINARY:
  1041.         curwp -> w_fmt_ptr = &binary_32_fmt;
  1042.         break;
  1043.  
  1044.     default:
  1045.         return (TRUE);
  1046.         break;
  1047.     }
  1048.  
  1049.     /* if we are in the middle of a search then use the proper format struc */
  1050.     if (read_pat_mode)
  1051.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1052.  
  1053.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1054.     wind_on_dot (curwp);
  1055.     curwp -> w_flag = WFHARD;
  1056.     update ();
  1057.     return (TRUE);
  1058. }
  1059.  
  1060. /*
  1061. * Display byte swaped.   This command causes the bytes
  1062. * that are displayed in WORD and DWORD mode to be swaped
  1063. * in the way that the INTEL microprocessors do it.
  1064. */
  1065. bool dispswapbyte (f, n, k)
  1066. {
  1067.     if ((curwp -> w_fmt_ptr -> r_size) == BYTES)
  1068.         return (TRUE);
  1069.  
  1070.     if (curwp -> w_intel_mode)
  1071.         curwp -> w_intel_mode = FALSE;
  1072.     else
  1073.         curwp -> w_intel_mode = TRUE;
  1074.  
  1075.     curwp -> w_flag = WFHARD;
  1076.     update ();
  1077.     return (TRUE);
  1078. }
  1079.  
  1080. /*
  1081. * Yank text back from the kill buffer. This
  1082. * is really easy. All of the work is done by the
  1083. * standard insert routines. All you do is run the loop,
  1084. * and check for errors. 
  1085. * An attempt has been made to fix the cosmetic bug
  1086. * associated with a yank when dot is on the top line of
  1087. * the window (nothing moves, because all of the new
  1088. * text landed off screen).
  1089. */
  1090. bool yank (f, n, k)
  1091. {
  1092.     register D16    c;
  1093.     register A32    i;
  1094.     char        buf[NCOL], buf1[NCOL];
  1095.  
  1096.     if (n < 0)
  1097.         return (FALSE);
  1098.     while (n--)
  1099.     {
  1100.         i = 0;
  1101.         save_buf_home ();
  1102.         while ((c = get_save_char ()) != (D16)-1)
  1103.         {
  1104.             if (linsert (1, c) == FALSE)
  1105.                 return (FALSE);
  1106.             if ((i & 0x2ff) == 0)
  1107.             {
  1108.                 sprintf (buf1, MSG_procing, R_POS_FMT(curwp));
  1109.                 sprintf (buf, buf1, (ulong)i);
  1110.                 writ_echo (buf);
  1111.                 /* check if we should quit */
  1112.                 if (ttkeyready ())
  1113.                 {
  1114.                     wind_on_dot_all();
  1115.                     if (ttgetc () == CTL_G)
  1116.                         return (FALSE);
  1117.                 }
  1118.             }
  1119.             ++i;
  1120.         }
  1121.     }
  1122.     /* update buffer display */
  1123.     if ((blistp -> b_nwnd != 0) &&
  1124.         (blistp -> b_type == BTLIST))
  1125.         listbuffers ();
  1126.  
  1127.     curwp -> w_flag |= WFHARD;
  1128.     return (TRUE);
  1129. }
  1130.  
  1131. /*
  1132. *   Link windows.   pvr
  1133. *   This function toggles the window linking function.
  1134. *   When linking is enabled all windows that look at 
  1135. *   the same buffer will be forced to have the same 
  1136. *   dot position.   Each window is then moved to be
  1137. *   positioned on the dot.   Thus when a user moves
  1138. *   arround a buffer all other views into that buffer 
  1139. *   will follow.
  1140. */
  1141.  
  1142. bool linkwind ()
  1143.  
  1144. {
  1145.     char    buf[NCOL];
  1146.  
  1147.     if (curwp -> w_bufp -> b_flag & BFLINK)
  1148.     {
  1149.         curwp -> w_bufp -> b_flag &= ~(BFLINK & 0xff);
  1150.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_unlink);
  1151.     }
  1152.     else
  1153.     {
  1154.         curwp -> w_bufp -> b_flag |= BFLINK;
  1155.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_link);
  1156.     }
  1157.     writ_echo (buf);
  1158.     return (TRUE);
  1159. }
  1160. /*
  1161. *   Print all bad keys to the screen and beep 
  1162. */
  1163. void    bad_key (key)
  1164. int     key;
  1165. {
  1166.     char    buf[NCOL];
  1167.  
  1168.     ttbeep ();
  1169.     sprintf (buf, MSG_bad_key);
  1170.     keyname (&buf[strlen (buf)], key);
  1171.     sprintf (&buf[strlen (buf)], ", %X", key);
  1172.     writ_echo (buf);
  1173. }
  1174.  
  1175. /*
  1176.  *    Combine sequential bytes from the rest of the windows
  1177.  *    into this window.   This is useful in combining PROM
  1178.  *    image files from odd and even bytes into one file.
  1179.  */
  1180. bool    n_way_combine (f, n, k)
  1181. {
  1182.     WINDOW * dest_wp, *src_wp;
  1183.     BUFFER *src_bp;
  1184.     A32    dotp;
  1185.     D8    byt;
  1186.     int j = 0;
  1187.     char        buf[NCOL], buf1[NCOL];
  1188.  
  1189.     /* save the destination window for later restore */
  1190.     dest_wp = curwp;
  1191.  
  1192.     if ((BUF_SIZE (curwp)) != (A32)0)
  1193.     {
  1194.         writ_echo (MSG_w_not_empty);
  1195.         return(FALSE);
  1196.     }
  1197.     /* Current window must be empty, modifiable and not the only one. */
  1198.     if ((BUF_SIZE (curwp) != 0) ||
  1199.         (curwp -> w_wndp == NULL) ||
  1200.         (curwp -> w_bufp -> b_flag & (BFVIEW | BFSLOCK)))
  1201.     {
  1202.         writ_echo (MSG_w_not_empty);
  1203.         return(FALSE);
  1204.     }
  1205.  
  1206.  
  1207.  
  1208.  
  1209.     for (;;)
  1210.     {
  1211.         /* step to the next window after the destination window */
  1212.         nextwind();
  1213.  
  1214.         /* as I cycle around the windows skip the destination window */
  1215.         if (curwp == dest_wp)
  1216.         {
  1217.             continue;
  1218.         }
  1219.         byt = DOT_CHAR(curwp) & 0xff;
  1220.         dotp = DOT_POS(curwp);   /* get the current dot position */
  1221.         /* move the dot position ahead in current buffer */
  1222.         if (move_ptr (curwp, 1L, TRUE, FALSE, TRUE) == FALSE)
  1223.         {
  1224.             /* did we advance? */
  1225.             if (DOT_POS(curwp) == dotp)
  1226.             {
  1227.                 wind_on_dot_all();
  1228.                 writ_echo (MSG_ok);
  1229.                 return (TRUE);   /* done all that we could */
  1230.             }
  1231.         }
  1232.  
  1233.         src_wp = curwp;
  1234.         src_bp = curwp -> w_bufp;
  1235.         curwp = dest_wp;
  1236.         curbp = dest_wp -> w_bufp;
  1237.         if (linsert (1, byt) == FALSE)
  1238.         {
  1239.             wind_on_dot_all();
  1240.             return (FALSE);    /* insert failed for some reason */
  1241.         }
  1242.         curwp = src_wp;
  1243.         curbp = src_bp;
  1244.         if ((j++ & 0x2ff) == 0)
  1245.         {
  1246.             sprintf (buf1, MSG_procing, R_POS_FMT(curwp));
  1247.             sprintf (buf, buf1, dotp);
  1248.             writ_echo (buf);
  1249.             /* check if we should quit */
  1250.             if (ttkeyready ())
  1251.             {
  1252.                 wind_on_dot_all();
  1253.                 if (ttgetc () == CTL_G)
  1254.                     return (FALSE);
  1255.             }
  1256.         }
  1257.     }
  1258. }
  1259.  
  1260. /*
  1261.  *    Split the current buffer into the rest of the windows.
  1262.  *    This is useful in splitting a binary file into PROM
  1263.  *    image files.
  1264.  */
  1265. bool    n_way_split (f, n, k)
  1266. {
  1267.     WINDOW  *src_wp;
  1268.     A32     b_size;
  1269.     D8    byt;
  1270.     int j = 0;
  1271.     char        buf[NCOL], buf1[NCOL];
  1272.  
  1273.     /* save the source window and buffer for later restore */
  1274.     src_wp = curwp;
  1275.  
  1276.     /* step to the next window after the source window */
  1277.     nextwind();
  1278.  
  1279.     /* check that all the destination windows are empty and modifiable */
  1280.     for (;;)
  1281.     {
  1282.         if ((BUF_SIZE (curwp) != 0) ||
  1283.             (curwp -> w_bufp -> b_flag & (BFVIEW | BFSLOCK)))
  1284.         {
  1285.             writ_echo (MSG_w_not_empty);
  1286.             return(FALSE);
  1287.         }
  1288.  
  1289.         /* force all windows to be refreshed */
  1290.         lchange (WFHARD);
  1291.         /* step to the next window */
  1292.         nextwind();
  1293.         /* stop after one pass around the windows */
  1294.         if (curwp == src_wp)
  1295.             break;
  1296.     }
  1297.  
  1298.     b_size = BUF_SIZE(src_wp);  /* get the buffer size */
  1299.  
  1300.     /* do the split until source is exhausted */
  1301.     for (;;)
  1302.     {
  1303.         /* step to the next window after the source window */
  1304.         nextwind();
  1305.  
  1306.         /* current window cannot be the source */
  1307.         if (curwp == src_wp)
  1308.             continue;
  1309.  
  1310.         byt = DOT_CHAR(src_wp) & 0xff;   /* get the byte to copy */
  1311.  
  1312.         /* are we at the end of the buffer */
  1313.         if (b_size == DOT_POS(src_wp))
  1314.         {
  1315.             wind_on_dot_all();
  1316.             writ_echo (MSG_ok);
  1317.             return (TRUE);
  1318.         }
  1319.         if (linsert (1, byt) == FALSE)
  1320.         {
  1321.             wind_on_dot_all();
  1322.             return (FALSE);
  1323.         }
  1324.         if ((j++ & 0x2ff) == 0)
  1325.         {
  1326.             sprintf (buf1, MSG_procing, R_POS_FMT(src_wp));
  1327.             sprintf (buf, buf1, DOT_POS(src_wp));
  1328.             writ_echo (buf);
  1329.             /* check if we should quit */
  1330.             if (ttkeyready ())
  1331.             {
  1332.                 wind_on_dot_all();
  1333.                 if (ttgetc () == CTL_G)
  1334.                     return (FALSE);
  1335.             }
  1336.         }
  1337.         if (move_ptr (src_wp, 1L, TRUE, FALSE, TRUE) == FALSE)
  1338.         {
  1339.             wind_on_dot_all();
  1340.             writ_echo (MSG_ok);
  1341.             return (TRUE);    /* hit the end of the source buffer */
  1342.         }
  1343.     }
  1344. }
  1345.  
  1346. void wind_on_dot_all ()
  1347. {
  1348.     WINDOW  *wp;
  1349.  
  1350.     wp = curwp;
  1351.     do
  1352.     {
  1353.         wind_on_dot (curwp);
  1354.         nextwind();
  1355.     }    while (wp != curwp);
  1356. }
  1357.